package com.suiwei.webservice.base.wsServer.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.springframework.stereotype.Component;
import org.w3c.dom.NodeList;

import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

/**
 * @author suiwei
 * @date 2023-04-24 11:10
 * 可选择，添加接口安全认证
 */
@Slf4j
@Component
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    public static final String USER_NAME ="suiwei";
    public static final String USER_PASSWORD ="suiwei";
    private SAAJInInterceptor saa = new SAAJInInterceptor();//创建拦截器
    //构造方法
    public AuthInterceptor(String phase) {
        super(Phase.PRE_PROTOCOL);
        super.getAfter().add(SAAJInInterceptor.class.getName());//添加拦截

    }
    public AuthInterceptor() {
        super(Phase.PRE_PROTOCOL);
        super.getAfter().add(SAAJInInterceptor.class.getName());//添加拦截
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        SOAPMessage soapMessage = message.getContent(SOAPMessage.class);//获取指定消息
        if (soapMessage==null){//没有消息内容
            this.saa.handleMessage(message);//走默认处理
            soapMessage= message.getContent(SOAPMessage.class);//尝试获取消息
        }
        SOAPHeader header = null;//SOAP头信息
        try {
            header = soapMessage.getSOAPHeader();//通过消息获取头信息
        } catch (SOAPException e) {
            log.info("获取投信息失败",e);
        }
        if (header==null){
            throw new Fault(new IllegalAccessException("找不到头信息"));
        }
        //soap是基于xml文件结构进行传输的，所以如果想要获取认证信息就必须进行相关的结构约定
        NodeList usernameNodeList = header.getElementsByTagName("username");//获取指定标签集合
        NodeList passwordNodeList = header.getElementsByTagName("password");//获取dom数据
        if(usernameNodeList.getLength()<1||passwordNodeList.getLength()<1){
            throw new Fault(new IllegalAccessException("找不到头信息，无法认证"));
        }
        String username = usernameNodeList.item(0).getTextContent().trim();
        String password = passwordNodeList.item(0).getTextContent().trim();
        if (USER_NAME.equals(username)&&USER_PASSWORD.equals(password)){
            log.info("认证成功！");
        }else {
            SOAPException soapException = new SOAPException("用户认证失败");
            log.info("用户认证失败！");
            throw new Fault(soapException);

        }


    }
}
